<!DOCTYPE html>
<html>
<head>
	<meta  http-equiv="Content-Type" content="text/html; charset=utf-8" >
	<title> 3n + 1 Game </title>
	<style type="text/css">
		th,td{			
			/*width: 20px;*/
			height: 26px;
			text-align: right;
			letter-spacing: 3px;
			font-family: 'arial black';
		}
		th{background-color: #FE3;}
		td{background-color: #555;color: #DDD;}
		td:nth-child(2) {color: #777;}
		td:nth-child(2) z{color: #DDD;}
	</style>
</head>
<body>
<a href="http://www.matrix67.com/blog/archives/6756">根据 Matrix67 博客中的题目所做的练习。</a>
<p>任意取一个正整数 n 。如果 n 是奇数，则把 n 变为 3 · n + 1 ；如果 n 是偶数，则把 n 变为 n/2 。不断重复操作，则最终一定会得到 1 。</p>
Input Number: <input type="number" id="ipt" />
<table id="viewer"></table>
<table>
	<thead>
	<tr><th>Decimal</th><th>Binary</th><th>Step</th><th>Weight</th></tr>
	</thead>
	<tbody id="insertRow"></tbody>	
</table>

<script >
	'use strict';

		const insertRow = document.querySelector('#insertRow');
		const viewer = document.getElementById('viewer');

		function step(num) {
			if (num === 1) return 1;
			//if(num >= Number.MAX_SAFE_INTEGER) return 0;
			if (num & 1) { return 3 * num + 1; }
			else { return num >> 1 }
		}


		function showSteps(num) {

			insertRow.textContent = '';

			let cst = 0;

			while (num >= 2) {

				cst++;

				// if(num & 1){      
				let tr = document.createElement("tr");

				let td1 = document.createElement("td");
				td1.textContent = num;

				let td2 = document.createElement("td");

				td2.innerHTML = to32Bit(num);
				//td2.setAttribute('b',str2);
				td2.setAttribute('v', num);
				td2.addEventListener('click', function (evn) {
					viewChange(this.getAttribute('v'));
				}, false)

				let td3 = document.createElement("td");
				td3.textContent = cst;

				let td4 = document.createElement("td");
				let tmp4 = num, wt = 0;
				while (tmp4 > 0) {
					if (tmp4 & 1) wt++;
					tmp4 = tmp4 >> 1;
				}
				td4.textContent = wt;

				tr.appendChild(td1);
				tr.appendChild(td2);
				tr.appendChild(td3);
				tr.appendChild(td4);
				insertRow.appendChild(tr);

				// }   

				num = step(num);
			}
		}

		function viewChange(num) {
			viewer.innerHTML = '';
			/*
			let tr1 =document.createElement("tr");
			  
			let td11 = document.createElement("td");
			td11.textContent = 'prime';
		  
			let td12 = document.createElement("td");
			td12.innerHTML = to32Bit(num);
		  
			let td13 = document.createElement('td');
			td13.textContent = num;
			*/

			function fmt(title, val) {
				return `<tr><td>${title}</td><td>${to32Bit(val)}</td><td>${val}</td>`;
			}

			viewer.innerHTML += fmt('n ', num);
			viewer.innerHTML += fmt('n << 1', num << 1);
			viewer.innerHTML += fmt('n << 1 ^ n', (num << 1) ^ num);
			viewer.innerHTML += fmt('n * 3', num * 3);
			viewer.innerHTML += fmt('n * 3 + 1', num * 3 + 1);

		}

		function to32Bit(num) {
			let str2 = Math.abs(parseInt(num, 10)).toString(2);
			str2 = '0'.repeat(32 - str2.length) + str2;
			return str2.replace(/(1)/g, '<z>$1</z>');
		}

		(() => {
			document.getElementById('ipt').addEventListener('change', function (evn) {
				showSteps(Math.abs(parseInt(this.value, 10)));
			}, false);
		})();
</script>
</body>
</html>